﻿using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Reflection;

namespace System.Linq
{
    public static class QueryBuilder
    {
        public static IQueryBuilder<T> Create<T>()
        {
            return new QueryBuilder<T>();
        }
    }

    internal class QueryBuilder<T> : IQueryBuilder<T>
    {
        Expression<Func<T, bool>> IQueryBuilder<T>.Expression
        {
            get
            {
                return RetrieveExpression();
            }
        }

        public ParameterExpression[] Parameters { get;set; }

        protected List<Expression> Expressions = new List<Expression>();

        public QueryBuilder()
        {
        }

        public void AppendExpression(Expression expression)
        {
            this.Expressions.Add(expression);
        }

        protected virtual Expression<Func<T, bool>> RetrieveExpression()
        {
            if (Expressions.Count == 0)
            {
                return (Expression<Func<T, bool>>) (x => true);
            }
            Expression expression = this.Expressions.Aggregate(Expression.AndAlso);

            return Expression.Lambda<Func<T, bool>>(expression, this.Parameters);
        }
    }
}

